package org.hismig.utils;

import java.io.File;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.jexl2.Expression;
import org.apache.commons.jexl2.JexlContext;
import org.apache.commons.jexl2.JexlEngine;
import org.apache.commons.jexl2.MapContext;
import org.apache.commons.jexl2.UnifiedJEXL;

/**
 * @declare: //TODO <br />
 *           This class created by Vansion.Hopihit on 2012-07-04 <br />
 *           <a href="mailto:vansionhopihit@gmail.com">Contact Me</a>
 * @version 1.0
 * @author Vansion.Hopihit
 * 
 */
public class StringTool {

	private static JexlEngine jexlEngine;
	private static UnifiedJEXL unifiedJEXL;

	public static boolean evaluate(String expression,
			Map<String, Object> context) {

		// use the jexl component to parse the expression, return the boolean
		// result

		if (null == jexlEngine) {
			jexlEngine = new JexlEngine();
		}

		if (null == unifiedJEXL) {
			unifiedJEXL = new UnifiedJEXL(jexlEngine);
		}

		UnifiedJEXL.Expression ex = unifiedJEXL.parse(expression);

		JexlContext jexlContext = new MapContext(context);

		// 1.parse expression; 2.evaluate

		Expression e = jexlEngine.createExpression(ex.evaluate(jexlContext)
				.toString());
		Object result = e.evaluate(jexlContext);

		return Boolean.parseBoolean(result.toString());
	}

	public static Set<String> getPlaceKeys(String src) {
		CheckTool.checkNotEmpty(src);

		Set<String> keys = new HashSet<String>();
		char[] chars = src.toCharArray();

		int start = src.indexOf("#{");
		int end = start;

		if (-1 != start) {
			for (; start < chars.length - 2; start++) {

				end = start + 2;
				if (chars[start] == '#') {
					if (chars[start + 1] == '{') {
						if (chars[start + 2] != '}') {

							for (; end < chars.length; end++) {
								if (chars[end] == '}') {

									keys.add(src.substring(start + 2, end));
									start = end + 1;
									break;
								} else if (end == chars.length - 1) {
									return keys;
								}

							}

						}
					}
				}
			}
		}

		return keys;
	}

	public static String replaceString(String src, String key, String replace) {
		CheckTool.checkNotEmpty(src);

		if (!isEmpty(replace)) {
			src = src.replaceAll("\\#\\{" + key + "\\}", replace);
		}

		return src;
	}

	public static String parseString(String src, Map<String, Object> map) {

		CheckTool.checkNotEmpty(src);
		CheckTool.checkNotNull(map);

		Set<String> keys = getPlaceKeys(src);

		for (String key : keys) {
			Object value = map.get(key);
			if (null != value) {
				src = replaceString(src, key, value.toString());
			} else {
				// can't find value to replace, then ignore
			}
		}

		return src;
	}

	public static boolean isEmpty(Object str) {
		return null == str || str.toString().isEmpty();
	}

	public static String trimBlank(String str) {
		if (null == str || str.isEmpty()) {
			return str;
		}

		Pattern p = Pattern.compile("^\\s*|\t|\r|\n|\\s*$");
		Matcher m = p.matcher(str);
		return m.replaceAll("");
	}

	public static boolean convertToBoolean(String str, boolean defalut) {
		if (null != str) {
			if (str.equalsIgnoreCase("TRUE")) {
				return true;
			}

			if (str.equalsIgnoreCase("FALSE")) {
				return false;
			}
		}

		return defalut;
	}

	public static String niceWord(Object word) {

		if (!isEmpty(word)) {
			return word.toString().substring(0, 1).toUpperCase()
					+ word.toString().substring(1).toLowerCase();
		}

		return null;
	}

	public static int getIntFormString(String str) {
		if (null == str || str.isEmpty() || !isNumeric(str)) {
			return 0;
		}

		return Integer.parseInt(str);
	}

	public static boolean isNumeric(String str) {
		// Pattern pattern = Pattern.compile("-?[0-9]+.?[0-9]+");
		Pattern pattern = Pattern.compile("^-?[0-9]+");
		Matcher isNum = pattern.matcher(str);
		if (!isNum.matches()) {
			return false;
		}
		return true;
	}

	public static String replacePath(String path) {

		String ret = path;

		if (!isEmpty(ret)) {
			ret = replaceFile(ret);

			if (!ret.endsWith(File.separator)) {
				ret += File.separator;
			}
		}

		return ret;
	}

	public static String replaceFile(String fileName) {
		String ret = fileName;

		if (!isEmpty(ret)) {
			ret = ret.replaceAll("\\\\", File.separator);
			ret = ret.replaceAll("/", "\\" + File.separator);
		}

		return ret;
	}

}
